﻿//Copyright (C) <2013>  <jonathan cleeve norton> All Rights Reserved 
//Contact jon.norton@fin-plus.co.uk website <http://www.fin-plus.co.uk/>
using System.Collections.Generic;
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Reflection;
using FinPlusCommon;
using System.Xml;
using System.IO;
using Microsoft.Win32;
using FinPlusComponents;
using u = FinPlusUtility.Utility;
using log = Logger.Logger;

namespace FinPlusWPFControls
{
    public partial class FinPlusConfigCheck : FinPlusControl
    {
        public override string Id { get; set; }
        public override string[] States { get { return new string[] { "FilePath", "Height", "Width", "Left", "Top", "InfoState" }; } }
        public override string[] TestStates { get { return new string[] { "ModelTest", "IsValid", "FilePath" }; } }
        public override IFinPlusFunctions Model { get { return _funcs; } }
        public override string ModelTest { get { return Model.ToString(); } }
        public override bool IsValid { get; set; }

        public string FilePath { get { return _filePath; } set { _filePath = value; tFile.Text = _filePath; } }
        public string InfoState { get { return GetInfoState(); } set { SetInfoState(value); } }

        private enum ConfigType { Client, Service, State };
        private const string XmlNode = "root/current";
        private const string ClientComponentAssembly = "finpluscomponents";
        private IFinPlusFunctions _funcs = new Functions();
        private IFinPlusFunction _infoParent;
        private ConfigType _configType;
        private Assembly _targetAssembly;
        private string _filePath, _infoPath, _serviceName;
  
        //construct
        public FinPlusConfigCheck()
        {
            InitializeComponent();
            cConfigType.ItemsSource = Enum.GetValues(typeof(ConfigType)).Cast<ConfigType>();
            cConfigType.SelectedItem = ConfigType.Client;
            IsValid = true;
        }

        //common control interface
        public override void Dock(object control, string dock)
        {
            try
            {
                if (control.GetType() == typeof(FinPlusParentService))
                    AddConnection((FinPlusParentService)control);
            }
            catch (Exception e)
            {
                gridUI.Children.Add(new FinPlusErrorDisplay(e));
                IsValid = log.Log(Logger.Level.Warning, e.Message, e);
            }
        }

        public override void Initialise()
        {

        }

        public override void CommandRouter(IFinPlusFunction func)
        {
            try
            {
                CaptureCommand(func);

                switch ((Commands)Enum.Parse(typeof(Commands), func.Name, true))
                {
                    case Commands.Refresh: FileConnect(tFile.Text); break;
                    case Commands.Cancel: Clear(); break;
                    case Commands.Play: Play(); break;
                    case Commands.Stop: ClearChildren(); break;
                    case Commands.File: FileLoad(func["Tag"].ToString()); break;
                    default: throw new Exception(string.Format("event not recognised {0}", func.Name));
                }
            }
            catch (Exception e)
            {
                IsValid = log.Log(Logger.Level.Warning, e.Message, e);
            }
        }

        public override void Dispose()  
        {
            if(_funcs != null)
                FinPlusAssembler.Dispose(_funcs);
        }

        //private
        private void AddConnection(FinPlusParentService conn)
        {
            try
            {
                Clear();
                _funcs = conn.Model;
                xmlLayout.xmlDocument = _funcs.ToXmlDoc();
                ShowInfos(_funcs);
            }
            catch (Exception e)
            {
                gridUI.Children.Add(new FinPlusErrorDisplay(e));
                log.Log(Logger.Level.Error, Id, Config, e.Message, e);
            }
        }

        private void ClearChildren()
        {
            testSubject.Text = "";
            gridUI.Children.Clear();
        }

        private void Play()
        {
            if (string.IsNullOrEmpty(_filePath)) return;

            try
            {
                _serviceName = _filePath.Split('\\').Last();

                gridUI.Children.Clear();

                _configType = (ConfigType)cConfigType.SelectedItem;
                _targetAssembly = _configType == ConfigType.Client ? Assembly.GetExecutingAssembly() : Assembly.LoadFile(u.GetAssemblyPath(Assembly.GetExecutingAssembly()) + ClientComponentAssembly + ".dll");

                FinPlusAssembler.Dispose(_funcs);
                var parentFunc = FinPlusAssembler.Construct(_funcs, new[]{_targetAssembly}, _serviceName.Split('.')[0]);

                ShowInfos(_funcs);

                if (_configType == ConfigType.Service)
                    ShowService(parentFunc);
                else if (_configType == ConfigType.Client)
                    ShowClient(parentFunc);

                testSubject.Text = _serviceName;
            }
            catch (Exception e)
            {
                IsValid = log.Log(Logger.Level.Warning, e.Message, e);
            }
        }

        private void ShowInfos(IFinPlusFunctions funcs)
        {
            var infos = FuncInfos.Get(funcs, _targetAssembly);
            var dataGrid = new FinPlusGroupGrid("Exclude:TimeStamp,FunctionName;ValueFunction:Function,Methods,Properties;ValueTriState:IsBuilt,IsValid", "Function,Methods,Properties", string.Empty, string.Empty, "True", "False") { Id = "InfoGrid" };
            var funcDynamics = new FuncDynamics(infos);
            
            dataGrid.Dock((object)funcDynamics, string.Empty);
            dataGrid.Dock(new FinPlusFilterbarTray() { Id = "InfoFilterbarTray" }, "Bottom");
            _infoParent = new Function() { Object = dataGrid };

            SetInfoState(_infoPath);
            gridInfos.Children.Add(dataGrid);
        }

        private void ShowService(IFinPlusFunction parentFunc)
        {
            var dataGrid = new FinPlusGroupGrid(string.Empty, string.Empty, string.Empty, string.Empty, "True", "False");
            var funcDynamics = new FuncDynamics(((IFinPlusComponent)parentFunc.Object).Model);
            
            dataGrid.Dock((object)funcDynamics, string.Empty);
            dataGrid.Dock(new FinPlusFilterbarTray(), "Bottom");
            gridUI.Children.Add(dataGrid);
        }

        private void ShowClient(IFinPlusFunction parentFunc)
        {
            FinPlusAssembler.InjectState(parentFunc, new Functions(_filePath.ToLower().Replace(".client", ".state"), XmlNode));
            gridUI.Children.Add((UserControl)parentFunc.Object);
        }

        private string GetInfoState()
        {
            if (_infoParent == null) return string.Empty;

            var path = u.GetAssemblyPath(Assembly.GetExecutingAssembly()) + "FinPlusClients\\InfoState.State";
            FinPlusAssembler.ExtractState(_infoParent, Environment.UserName).ToXmlDoc(XmlNode).Save(path);
            return path;
        }

        private void SetInfoState(string path)
        {
            if (!string.IsNullOrEmpty(path))
                FinPlusAssembler.InjectState(_infoParent, new Functions(_infoPath = path, XmlNode));
        }

        private void FileLoad(string path)
        {
            tFile.Text = _filePath = path;
            FileConnect(tFile.Text);
        }

        private void FileConnect(string path, string serviceType = "test", string serviceName = "test")
        {
            var service = new FinPlusParentService(serviceType, serviceName, string.Empty, path, XmlNode, false, true);
            AddConnection(service);;
        }

        private void Clear()
        {
            try
            {
                xmlLayout.xmlDocument = null;
                gridUI.Children.Clear();
                ShowInfos(_funcs);
            }
            catch (Exception e)
            {
                log.Log(Logger.Level.Error, Id, Config, e.Message, e);
            }
        }

        private void FileRouter(string command)
        {
            gridUI.Children.Clear();
            var d = new OpenFileDialog()
            {
                FileName = "Document",
                DefaultExt = "." + cConfigType.SelectedItem,
                Filter = string.Format("{0} documents (.{0})|*.{0}", cConfigType.SelectedItem)
            };
            var res = d.ShowDialog();

            if (res == true)
                CommandRouter(new Function(command, Id, User, -1, d.FileName));
        }

        //cmds
        private new enum Commands { Refresh, Cancel, Play, Stop, File }

        //events
        private void Refresh_OnClick(object sender, RoutedEventArgs a) { CommandRouter(new Function(Commands.Refresh.ToString(), Id, User)); }
        private void Cancel_OnClick(object sender, RoutedEventArgs a) { CommandRouter(new Function(Commands.Cancel.ToString(), Id, User)); }
        private void Play_OnClick(object sender, RoutedEventArgs a) { CommandRouter(new Function(Commands.Play.ToString(), Id, User)); }
        private void Stop_OnClick(object sender, RoutedEventArgs a) { CommandRouter(new Function(Commands.Stop.ToString(), Id, User)); }
        private void File_OnClick(object sender, RoutedEventArgs a) { FileRouter(Commands.File.ToString()); } 
    }
}





























































































//Copyright2013<jnrton>AllRightsReserved 
//Contact j.nrton@finpus